package com.unittec.zk.provider.utils;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.List;

import org.springframework.beans.BeanUtils;
import org.springframework.util.CollectionUtils;

import com.alibaba.fastjson.JSON;

/**
 * @author wuxinwei
 */
public class CopyListUtils {

    /**
     * copyList
     *
     * @param sourceList
     * @param targetClass
     * @return
     */
    public static <T> List<T> copyList(List<?> sourceList, Class<T> targetClass) {
        if (sourceList == null || CollectionUtils.isEmpty(sourceList)) {
            return new ArrayList<>();
        }
        return JSON.parseArray(JSON.toJSONString(sourceList), targetClass);
    }

    /**
     * @param sourceList
     * @param targetClass
     * @param <E>
     * @param <T>
     * @return
     */
    public static <E, T> List<T> copyToList(List<E> sourceList, Class<T> targetClass) {
        if (sourceList == null || CollectionUtils.isEmpty(sourceList)) {
            return new ArrayList<>();
        }
        List<T> output = new ArrayList<>(sourceList.size());
        for (E source : sourceList) {
            T target = BeanUtils.instantiateClass(targetClass);
            BeanUtils.copyProperties(source, target);
            output.add(target);
        }
        return output;

    }

    /**
     * @param sourceList
     * @param <T>
     * @return
     */
    @SuppressWarnings("unchecked")
    public static <T> List<T> copyToList(List<T> sourceList) {
        if (sourceList == null || CollectionUtils.isEmpty(sourceList)) {
            return new ArrayList<>();
        }
        ByteArrayInputStream byteIn = null;
        ObjectInputStream in = null;
        try (ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
            ObjectOutputStream out = new ObjectOutputStream(byteOut)) {
            out.writeObject(sourceList);
            byteIn = new ByteArrayInputStream(byteOut.toByteArray());
            in = new ObjectInputStream(byteIn);
            return (List<T>)in.readObject();
        } catch (IOException | ClassNotFoundException e) {
            throw new RuntimeException(e.getLocalizedMessage());
        } finally {
            try {
                if (in != null) {
                    in.close();
                }
                if (byteIn != null) {
                    byteIn.close();
                }
            } catch (IOException e) {
            }
        }
    }
}
